﻿using Gdmec.Cache;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using XLua;

namespace Gdmec.Audio
{
    public class AudioManager : MonoBehaviour
    {
        public static AudioManager Instance { get; private set; }
        private Queue<AudioSource> source_pools = new Queue<AudioSource>();
        private List<AudioSource> work_pools = new List<AudioSource>();
        private Dictionary<AudioSource, float> source_times = new Dictionary<AudioSource, float>();
        void Awake()
        {
            Instance = this;
        }
        void OnDestroy()
        {
            Instance = null;
        }

        public static AudioSource GetSource() 
        {
            AudioSource source;
            if (Instance.source_pools.Count > 0)
            {
                source = Instance.source_pools.Dequeue();
            }
            else 
            {
                source = Instance.gameObject.AddComponent<AudioSource>();
            }
            Instance.work_pools.Add(source);
            return source;
        }

        [LuaCallCSharp]
        public static void PlayMusic(string name) 
        {
            AudioSource source = GetSource();
            source.clip = CacheManager.GetAudioClip(GetPathMP3(name));
            source.Play();
            Instance.source_times.Add(source, Time.realtimeSinceStartup + source.clip.length);
        }

        public static string GetPathMP3(string name) 
        {
            return string.Format("audio/mp3.gdmec/{0}",name);
        }

        private AudioSource temp_source;
        private float temp_source_time;
        private void Update()
        {
            if (Instance.work_pools.Count <= 0) return;
            var list = Instance.work_pools.ToList();
            for (int i = 0; i < list.Count; i++)
            {
                temp_source = list[i];
                if (Instance.source_times.TryGetValue(temp_source, out temp_source_time)) 
                {
                    if (Time.realtimeSinceStartup >= temp_source_time) 
                    {
                        temp_source.Stop();
                        Instance.source_pools.Enqueue(temp_source);
                        Instance.work_pools.Remove(temp_source);
                        Instance.source_times.Remove(temp_source);
                        temp_source = null;
                    }
                }
            }
        }

    }
}
